package agents.fire;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;

import java.awt.Point;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import log.Action;
import log.ContadorEventos;

import org.apache.log4j.Logger;

import agents.environment.Map;

import com.avanti.routes.ListaCuadrantes;

import es.ucm.fdi.agents.yellowPages.YellowPages;

public class FirePropagationBehaviour extends TickerBehaviour
{
	static Logger logger = Logger.getLogger(FireAgent.class);

	Random r = new Random(100);
	ArrayList<Point> posiciones;
	private AID[] listaAgentesComunicacion;
	private AID[] listaAgentesMundo;

	private YellowPages paginasAmarillas;
	private ArrayList<Integer> cuadrantes;
	private boolean isInicio = true;
	public static int radio = 1;

	public FirePropagationBehaviour(Agent a, long period)
	{
		super(a, period);
		this.posiciones = (ArrayList<Point>) ((FireAgent) a).getPosiciones();
		this.cuadrantes = new ArrayList<Integer>();
		
		for (Iterator<Point> iterator = posiciones.iterator(); iterator.hasNext();)
		{
			comprobarNuevoCuadrante(iterator.next());
		}

		this.paginasAmarillas = new YellowPages();
		// //System.out.println("### FirePropagationBehaviour");
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	long lastTimePropagated = 0;

	@Override
	protected void onTick()
	{
		listaAgentesComunicacion = paginasAmarillas.buscarServicio("envio-coordenadas", myAgent);
		listaAgentesMundo = paginasAmarillas.buscarServicio("world", myAgent);

		if (listaAgentesComunicacion != null && listaAgentesComunicacion.length > 0)
		{
			if (System.currentTimeMillis() - lastTimePropagated > 2000)
			{
				// ////System.out.println("### On tick FIRE!!!!");
				propagar();
				enviaCoordenadas();
			}
		}
	}

	private void enviaCoordenadas()
	{
		ACLMessage res = new ACLMessage(ACLMessage.AGREE);

		try
		{
			if(isInicio){
				isInicio = false;
				int idCuadrante = ListaCuadrantes.getInstance().getIdCuadrante(posiciones.get(0));
				logger.info(ContadorEventos.addEvent(Integer.toString(idCuadrante),Action.INICIO_FOCO, "("+posiciones.get(0).x+","+posiciones.get(0).y+")"));
			}
			res.setContentObject(posiciones);
			// res.setContent("_coordenadasFuego"); //posSb.toString());
			res.addReceiver(listaAgentesComunicacion[0]);
			res.addReceiver(listaAgentesMundo[0]);
			myAgent.send(res);
			
			
			logger.info(ContadorEventos.addEvent("many", Action.ENVIAR_MSJ, "posiciones"));
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void propagar()
	{
		List<Point> newPoints = new ArrayList<Point>();
		for (Iterator<Point> iterator = posiciones.iterator(); iterator.hasNext();)
		{
			Point point = iterator.next();

			addNewPosition(newPoints, point, -radio, 0);
			addNewPosition(newPoints, point, 0, -radio);
			addNewPosition(newPoints, point, radio, 0);

			addNewPosition(newPoints, point, 0, radio);

			// // Diagonales
			// addNewPosition(newPoints, point, -radio, radio);
			// addNewPosition(newPoints, point, radio, -radio);
			// addNewPosition(newPoints, point, radio, radio);
			// addNewPosition(newPoints, point, -radio, -radio);

		}

		posiciones.addAll(newPoints);

		lastTimePropagated = System.currentTimeMillis();
	}

	private void addNewPosition(List<Point> listToAdd, Point p, int i, int j)
	{
		if (!Map.getInstance().isWall(p.x + i, p.y + j) && !listToAdd.contains(new Point(p.x + i, p.y + j)) && !posiciones.contains(new Point(p.x + i, p.y + j)))
		{
			comprobarNuevoCuadrante(new Point(p.x + i, p.y + j));
			listToAdd.add(new Point(p.x + i, p.y + j));
		}
	}

	private void comprobarNuevoCuadrante(Point p)
	{
		Integer idCuadrante = ListaCuadrantes.getInstance().getIdCuadrante(p);
		if (!cuadrantes.contains(idCuadrante))
		{
			logger.info(ContadorEventos.addEvent(Integer.toString(idCuadrante), Action.ACCESO, Integer.toString(idCuadrante)));
			ListaCuadrantes.getInstance().setCuadranteInFire(idCuadrante);
			cuadrantes.add(idCuadrante);
		}
	}
}
